package com.bocloud.cmp.service.resource;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.bocloud.cmp.dao.BeanDetailDao;
import com.bocloud.cmp.dao.NetworkDeviceDao;
import com.bocloud.cmp.entity.resource.NetworkDevice;
import com.bocloud.cmp.enums.VMStatus;
import com.bocloud.cmp.interfaces.resource.NetworkDeviceService;
import com.bocloud.cmp.model.NetworkDeviceBean;
import com.bocloud.common.model.BsmResult;
import com.bocloud.common.model.GridBean;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.SimpleBean;
import com.bocloud.common.ssh.SSH;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.GridHelper;
import com.bocloud.coordinator.harmony.HarmonyLock;
import com.bocloud.coordinator.harmony.LockFactory;
import com.google.common.collect.Maps;

@Service("networkDeviceService")
public class NetworkDeviceServiceImpl implements NetworkDeviceService {

	private static Logger logger = LoggerFactory.getLogger(NetworkDeviceServiceImpl.class);
	@Autowired
	private NetworkDeviceDao networkDeviceDao;
	@Autowired
	private BeanDetailDao beanDetailDao;
	@Autowired
	private LockFactory lockFactory;

	@Override
	public BsmResult create(NetworkDevice device, Long userId) {
		try {
			device.setCreaterId(userId);
			device.setMenderId(userId);
			device.setStatus(VMStatus.STOPPED.name());
			networkDeviceDao.save(device);
		} catch (Exception e) {
			logger.error("Create device fail:", e);
			return new BsmResult(false, "添加失败");
		}
		return new BsmResult(true, device, "添加成功");
	}

	@Override
	public BsmResult modify(NetworkDeviceBean bean, Long userId) {
		String path = NetworkDevice.class.getSimpleName() + "_" + bean.getId();
		HarmonyLock lock = null;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时");
			}

			NetworkDevice device = this.networkDeviceDao.query(bean.getId());
			if (null == device) {
				logger.warn("NetworkDevice does not exist!");
				return new BsmResult(false, "数据不存在");
			}
			BeanUtils.copyProperties(bean, device);
			device.setMenderId(userId);
			this.networkDeviceDao.update(device);
			return new BsmResult(true, "修改成功");
		} catch (Exception e) {
			logger.error("Modify device fail:", e);
			return new BsmResult(false, "修改失败", null, null);
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}

	@Override
	public BsmResult remove(Long id, Long userId) {
		String path = NetworkDevice.class.getSimpleName() + "_" + id;
		HarmonyLock lock = null;
		Boolean result = false;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时");
			}
			NetworkDevice device = this.networkDeviceDao.query(id);
			if (null == device) {
				logger.warn("NetworkDevice does not exist!");
				return new BsmResult(false, "数据不存在");
			}
			result = this.networkDeviceDao.remove(id, userId);
			return result ? new BsmResult(true, "删除成功") : new BsmResult(true, "已被删除");
		} catch (Exception e) {
			logger.error("Remove device fail:", e);
			return new BsmResult(false, "删除失败", null, null);
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}

	@Override
	public BsmResult detail(Long id) {
		try {
			NetworkDevice device = this.beanDetailDao.getNetworkDeviceBean(id);
			return new BsmResult(true, device, "查询成功");
		} catch (Exception e) {
			logger.error("Query device fail:", e);
			return new BsmResult(false, "查询失败", null, null);
		}

	}

	@Override
	public BsmResult list(int page, int rows, List<Param> params, Map<String, String> sorter, Boolean simple) {
		List<NetworkDevice> list = null;
		List<SimpleBean> beans = null;
		int total = 0;
		GridBean gridBean = null;
		try {
			if (null == params) {
				params = new ArrayList<Param>();
			}
			if (null == sorter) {
				sorter = Maps.newHashMap();
			}
			sorter.put("gmtCreate", Common.ONE);
			total = this.networkDeviceDao.count(params);
			if (simple) {
				beans = this.networkDeviceDao.list(params, sorter);
				gridBean = new GridBean(1, 1, total, beans);
			} else {
				list = this.networkDeviceDao.list(page, rows, params, sorter);
				gridBean = GridHelper.getBean(page, rows, total, list);
			}
			return new BsmResult(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("Query device list fail:", e);
			return new BsmResult(false, "查询失败", null, null);
		}
	}

	@Override
	public BsmResult start(Long id) {
		String path = NetworkDevice.class.getSimpleName() + "_" + id;
		HarmonyLock lock = null;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时", "", "");
			}
			NetworkDevice device = networkDeviceDao.query(id);
			String startCommand = device.getStartCommand();
			if (null == startCommand) {
				return new BsmResult(false, "请添加启动脚本！");
			}
			Integer port = null;
			if (!StringUtils.isEmpty(device.getServicePort())) {
				port = Integer.valueOf(device.getServicePort());
			}
			SSH ssh = null;
			if (null == port) {
				ssh = new SSH(device.getServiceIp(), device.getAccount(), device.getPassword());
			} else {
				ssh = new SSH(device.getServiceIp(), device.getAccount(), device.getPassword(), port);
			}
			if (!ssh.connect()) {
				logger.error("ssh connect failure!");
				return new BsmResult(false, "启动失败!");
			}
			String result = ssh.executeWithResult(startCommand);
			if (null == result) {
				return new BsmResult(false, "启动失败!");
			}
			device.setStatus(VMStatus.RUNNING.name());
			networkDeviceDao.update(device);
			return new BsmResult(true, "启动成功!");
		} catch (Exception e) {
			logger.error("start middleware failure:", e);
			return new BsmResult(false, "启动失败!");
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}

	@Override
	public BsmResult batchRemove(String params, Long userId) {
		try {
			String[] idArray = params.split(",");// 要操作的设备id
			String networkDeviceName = "";// 重启失败的网络名称
			if (null != idArray && idArray.length != 0) {
				for (String id : idArray) {
					// 删除设备
					BsmResult result = this.remove(Long.parseLong(id), userId);
					if (!result.isSuccess()) {
						// 获取失败设备的名称
						NetworkDevice networkDevice = networkDeviceDao.query(Long.parseLong(id));
						networkDeviceName += networkDevice.getName();
					}
				}
			}
			// 返回操作失败的设备的名称
			if (networkDeviceName.length() > 0) {
				return new BsmResult(false, "网络设备" + networkDeviceName + "删除失败");
			}
		} catch (Exception e) {
			logger.error("exception" + e);
			return new BsmResult(false, "删除失败");
		}
		return new BsmResult(true, "网络设备删除成功");
	}

	@Override
	public BsmResult batchStart(String params, Long userId) {
		try {
			String[] idArray = params.split(",");// 要操作的设备的id
			String networkDeviceName = "";// 操作失败的设备的名称
			if (null != idArray && idArray.length > 0) {
				for (String id : idArray) {
					// 启动设备
					BsmResult result = this.start(Long.parseLong(id));
					if (!result.isSuccess()) {
						// 获取操作失败的网络设备
						NetworkDevice networkDevice = networkDeviceDao.query(Long.parseLong(id));
						networkDeviceName += networkDevice.getName();
					}
				}
			}
			// 返回操作失败的设备的名称
			if (networkDeviceName.length() > 0) {
				return new BsmResult(false, "网络设备" + networkDeviceName + "启动失败");
			}
		} catch (Exception e) {
			logger.error("exception" + e);
			return new BsmResult(false, "网络设备启动失败");
		}
		return new BsmResult(true, "网络设备启动成功");
	}

	@Override
	public BsmResult batchStop(String params, Long userId) {
		try {
			String[] idArray = params.split(",");// 要操作的设备id
			String networkDeviceName = "";// 操作失败的设备名称
			if (idArray != null && idArray.length > 0) {
				for (String id : idArray) {
					// 停止设备
					BsmResult result = this.stop(Long.parseLong(id));
					if (!result.isSuccess()) {
						// 获取失败的设备
						NetworkDevice networkDevice = networkDeviceDao.query(Long.parseLong(id));
						networkDeviceName += networkDevice.getName();
					}
				}
			}
			// 返回操作失败的设备名称
			if (networkDeviceName.length() > 0) {
				return new BsmResult(false, "网络设备" + networkDeviceName + "停止失败");
			}
		} catch (Exception e) {
			logger.error("exception" + e);
			return new BsmResult(false, "网络设备停止失败");
		}
		return new BsmResult(true, "网络设备停止成功");
	}

	@Override
	public BsmResult stop(Long id) {
		String path = NetworkDevice.class.getSimpleName() + "_" + id;
		HarmonyLock lock = null;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时", "", "");
			}
			NetworkDevice device = networkDeviceDao.query(id);
			String stopCommand = device.getStopCommand();
			if (null == stopCommand) {
				return new BsmResult(false, "请添加停止脚本！");
			}
			Integer port = null;
			if (!StringUtils.isEmpty(device.getServicePort())) {
				port = Integer.valueOf(device.getServicePort());
			}
			SSH ssh = null;
			if (null == port) {
				ssh = new SSH(device.getServiceIp(), device.getAccount(), device.getPassword());
			} else {
				ssh = new SSH(device.getServiceIp(), device.getAccount(), device.getPassword(), port);
			}
			if (!ssh.connect()) {
				logger.error("ssh connect failure!");
				return new BsmResult(false, "停止失败!");
			}
			String result = ssh.executeWithResult(stopCommand);
			if (null == result) {
				return new BsmResult(false, "停止失败!");
			}
			device.setStatus(VMStatus.STOPPED.name());
			networkDeviceDao.update(device);
			return new BsmResult(true, "停止成功!");
		} catch (Exception e) {
			logger.error("start networkDevice failure:", e);
			return new BsmResult(false, "停止失败!");
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}

}
